import direct.directbase.DirectStart
from panda3d.core import GraphicsOutput
from panda3d.core import Filename,Texture
from panda3d.core import CardMaker
from panda3d.core import Point3,Vec3,Vec4,BitMask32
from panda3d.core import NodePath,TextNode
from panda3d.core import AmbientLight,DirectionalLight
from panda3d.core import CollisionTraverser,CollisionNode
from panda3d.core import CollisionHandlerQueue,CollisionRay
from panda3d.core import GeomNode
from direct.showbase.DirectObject import DirectObject
from direct.gui.OnscreenText import OnscreenText
from direct.task.Task import Task
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import *
from random import uniform
from math import sqrt,fabs
from direct.gui.DirectGui import *
import sys,os,time

map = []

class space():
    def __init__(self):
        self.locx = 0
        self.locy = 0
        self.type = 1 #0 = Empty, 1 = Normal, 2 = Blocked
        self.canReach = False
        self.m = loader.loadModel("models/DungeonTile1")
        
    def changePos(self,x,y):
        self.locx = x
        self.locy = y
        
    

class player():
    global map
    def __init__(self):
        #RPG system stats
        self.speed = 3
        
        #Other stats        
        self.locx = 0
        self.locy = 0
        self.m = Actor("models/Teapot.X")
        self.m.setScale(0.1,0.1,0.1)
        self.m.reparentTo(render)
        self.m.setPos(map[self.locx][self.locy].m.getBounds().getCenter())
        print self.m
        
    def move(self,x,y):
        self.m.loop("Teapot")
        self.m.headsUp(map[x][y].m)
        i = LerpPosInterval(self.m,
            duration=.5*sqrt((x - self.locx)**2 + (y - self.locy)**2),
            pos=map[x][y].m.getBounds().getCenter(),            
            startPos=self.m.getPos(),
            other=None,
            blendType = "noBlend",
            bakeInStart = 1,
            fluid = 0,
            name=None)
        self.locx = x
        self.locy = y
        map[x][y].m.setTexture(loader.loadTexture("textures/Tile1HV.bmp"),1)   
        i.start()
            


class App(DirectObject):
    def __init__(self):
        base.disableMouse()
        camera.setPos(15,-66.8,60)
        camera.setHpr (0,-37.1,0)
        self.create_map(10,10)
        self.player1 = player()
        #Bool
        self.moveTurn = False
        #Textures
        self.normalTex = loader.loadTexture("textures/Tile1.bmp")
        self.mSelTex = loader.loadTexture("textures/Tile1HV.bmp")
        self.mTex = loader.loadTexture("textures/Tile1HL.bmp")
        
        #GUI
        actionFrame = DirectFrame(frameColor=(0,255,255,0.3),
            frameSize=(-0.4,0.3,-0.2,0.3),
            pos=(1.035,0,-0.799))
            
        mButton = DirectButton(text = "Move",
            pos=(0.765,0,-0.58),scale=(0.1,0.1,0.1),command = self.moveClicked)
        
        self.picker = CollisionTraverser()            #Make a traverser
        self.pq = CollisionHandlerQueue()  
        self.pickerNode = CollisionNode('mouseRay')
        self.pickerNP = camera.attachNewNode(self.pickerNode)
        self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        self.picker.addCollider(self.pickerNP, self.pq)
        
        self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask')
        
        self.selSquare = None
        self.hovSquare = None
        self.accept("escape", sys.exit, [0])
        #self.accept("e", self.printText)
        self.accept("mouse1", self.selSpace)
        self.accept("mouse3", self.printLoc)
        base.setBackgroundColor(0, 0, 0)    #Set the background to black
    
    def printText(self):
        print camera.getPos()
        print camera.getHpr()
       
    def create_map(self,x,y):
        global map
        map = [[space() for i in range(x)] for i in range (y)]
        for i,l in enumerate(map):
            for a,b in enumerate(l):
                b.m.reparentTo(render)
                b.m.setPos(i * 5.318, a * 5.318, 0)
                b.m.setScale(0.1)
                b.m.setTag("Tile",str(a)+ "," + str(i))
                b.changePos(a,i)
                #self.tiles[str(a)] = b
    
    def selSpace(self):
        global map                
        self.selSquare = self.hovSquare
        obj = self.selSquare 
        tagName = obj.getNetTag('Tile') 
        realobj = map[int(tagName[0])][int(tagName[2])]
        #import pdb; pdb.set_trace()
        if (self.moveTurn == True and self.selSquare != None):
            if (realobj.canReach == True):
                self.player1.move(realobj.locx,realobj.locy)   
                
                for i,l in enumerate(map):
                    for a,b inimport direct.directbase.DirectStart
from panda3d.core import GraphicsOutput
from panda3d.core import Filename,Texture
from panda3d.core import CardMaker
from panda3d.core import Point3,Vec3,Vec4,BitMask32
from panda3d.core import NodePath,TextNode
from panda3d.core import AmbientLight,DirectionalLight
from panda3d.core import CollisionTraverser,CollisionNode
from panda3d.core import CollisionHandlerQueue,CollisionRay
from panda3d.core import GeomNode
from direct.showbase.DirectObject import DirectObject
from direct.gui.OnscreenText import OnscreenText
from direct.task.Task import Task
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import *
from random import uniform
from math import sqrt,fabs
from direct.gui.DirectGui import *
import sys,os,time

map = []

class space():
    def __init__(self):
        self.locx = 0
        self.locy = 0
        self.type = 1 #0 = Empty, 1 = Normal, 2 = Blocked
        self.canReach = False
        self.m = loader.loadModel("models/DungeonTile1")
        
    def changePos(self,x,y):
        self.locx = x
        self.locy = y
        
    

class player():
    global map
    def __init__(self):
        #RPG system stats
        self.speed = 3
        
        #Other stats        
        self.locx = 0
        self.locy = 0
        self.m = Actor("models/Teapot.X")
        self.m.setScale(0.1,0.1,0.1)
        self.m.reparentTo(render)
        self.m.setPos(map[self.locx][self.locy].m.getBounds().getCenter())
        print self.m
        
    def move(self,x,y):
        self.m.loop("Teapot")
        self.m.headsUp(map[x][y].m)
        i = LerpPosInterval(self.m,
            duration=.5*sqrt((x - self.locx)**2 + (y - self.locy)**2),
            pos=map[x][y].m.getBounds().getCenter(),            
            startPos=self.m.getPos(),
            other=None,
            blendType = "noBlend",
            bakeInStart = 1,
            fluid = 0,
            name=None)
        self.locx = x
        self.locy = y
        map[x][y].m.setTexture(loader.loadTexture("textures/Tile1HV.bmp"),1)   
        i.start()
            


class App(DirectObject):
    def __init__(self):
        base.disableMouse()
        camera.setPos(15,-66.8,60)
        camera.setHpr (0,-37.1,0)
        self.create_map(10,10)
        self.player1 = player()
        #Bool
        self.moveTurn = False
        #Textures
        self.normalTex = loader.loadTexture("textures/Tile1.bmp")
        self.mSelTex = loader.loadTexture("textures/Tile1HV.bmp")
        self.mTex = loader.loadTexture("textures/Tile1HL.bmp")
        
        #GUI
        actionFrame = DirectFrame(frameColor=(0,255,255,0.3),
            frameSize=(-0.4,0.3,-0.2,0.3),
            pos=(1.035,0,-0.799))
            
        mButton = DirectButton(text = "Move",
            pos=(0.765,0,-0.58),scale=(0.1,0.1,0.1),command = self.moveClicked)
        
        self.picker = CollisionTraverser()            #Make a traverser
        self.pq = CollisionHandlerQueue()  
        self.pickerNode = CollisionNode('mouseRay')
        self.pickerNP = camera.attachNewNode(self.pickerNode)
        self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        self.picker.addCollider(self.pickerNP, self.pq)
        
        self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask')
        
        self.selSquare = None
        self.hovSquare = None
        self.accept("escape", sys.exit, [0])
        #self.accept("e", self.printText)
        self.accept("mouse1", self.selSpace)
        self.accept("mouse3", self.printLoc)
        base.setBackgroundColor(0, 0, 0)    #Set the background to black
    
    def printText(self):
        print camera.getPos()
        print camera.getHpr()
       
    def create_map(self,x,y):
        global map
        map = [[space() for i in range(x)] for i in range (y)]
        for i,l in enumerate(map):
            for a,b in enumerate(l):
                b.m.reparentTo(render)
                b.m.setPos(i * 5.318, a * 5.318, 0)
                b.m.setScale(0.1)
                b.m.setTag("Tile",str(a)+ "," + str(i))
                b.changePos(a,i)
                #self.tiles[str(a)] = b
    
    def selSpace(self):
        global map                
        self.selSquare = self.hovSquare
        obj = self.selSquare 
        tagName = obj.getNetTag('Tile') 
        realobj = map[int(tagName[0])][int(tagName[2])]
        #import pdb; pdb.set_trace()
        if (self.moveTurn == True):
            if (realobj.canReach == True):
                self.player1.move(realobj.locx,realobj.locy)   
                
                for i,l in enumerate(map):
                    for a,b in enumerate(l):
                        map[a][i].m.setTexture(self.normalTex,1)
            
            self.moveTurn = False
        else:
            self.moveClicked()
            
    def moveClicked(self):
        global map
        self.moveTurn = True
        for i,l in enumerate(map):
            for a,b in enumerate(l):
                if (sqrt((b.locx - self.player1.locx )**2 + (b.locy - self.player1.locy )**2 ) <= self.player1.speed):
                    map[b.locx][b.locy].m.setTexture(self.mTex,1)
                    map[b.locx][b.locy].canReach = True
                else:
                    map[b.locx][b.locy].canReach = False
        
        base.graphicsEngine.renderFrame()
    def printLoc(self):
        obj = self.hovSquare #.findNetTag("Tile")
        rockName = obj.getNetTag('Tile') 
                
        realobj = map[int(rockName[0])][int(rockName[2])]
                
        print "HELLO"
        print realobj.locx, ",", realobj.locy
        print map[realobj.locx][realobj.locy].m.getTexture()
        #import pdb; pdb.set_trace()
    
    def mouseTask(self, task):
        self.selSquare = None
        if base.mouseWatcherNode.hasMouse():
          #get the mouse position
          mpos = base.mouseWatcherNode.getMouse()
          
          #Set the position of the ray based on the mouse position
          self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
          
          #If we are dragging something, set the position of the object
          #to be at the appropriate point over the plane of the board
           #Gets the point described by pickerRay.getOrigin(), which is relative to
        #camera, relative instead to render
        nearPoint = render.getRelativePoint(camera, self.pickerRay.getOrigin())
            #Same thing with the direction of the ray
        nearVec = render.getRelativeVector(camera, self.pickerRay.getDirection())
        
      #Do the actual collision pass (Do it only on the squares for
      #efficiency purposes)
        self.picker.traverse(render)
        if self.pq.getNumEntries() > 0:
        #if we have hit something, sort the hits so that the closest
        #is first, and highlight that node
            self.pq.sortEntries()
            i = self.pq.getEntry(0).getIntoNodePath()
        #Set the highlight on the picked square
            self.hovSquare = i
        return Task.cont
        
            
app = App()
run()
            
    
"""class App(DirectObject):
    def __init__(self):
        self.tile = loader.loadModel("models/DungeonTile1")
        self.tile.setPos (0,70,0)
        self.tile.setHpr (0,45,0)
        self.tile.setScale(0.1)
        self.tile.reparentTo(render)
        
        self.tile2 = loader.loadModel("models/DungeonTile1")
        self.tile2.setPos (5.318,70,0)
        self.tile2.setHpr (0,45,0)
        self.tile2.setScale(0.1)
        self.tile2.reparentTo(render)
        
        self.title = OnscreenText(
            text="My Program",
            style=1, 
            fg=(1,1,1,1), 
            pos=(0,0), 
            scale = .07
        )
      

        camera.setPos (0,-60,0)
        camera.setHpr (0,-90,0)
        self.accept("escape", sys.exit, [0])
        self.accept("e", self.printText)
        base.setBackgroundColor(0, 0, 0)    #Set the background to black
    
    def printText(self):
        print camera.getPos()
    
app = App()
run()""" enumerate(l):
                        map[a][i].m.setTexture(self.normalTex,1)
                
            self.moveTurn = False
            
    def moveClicked(self):
        global map
        self.moveTurn = True
        for i,l in enumerate(map):
            for a,b in enumerate(l):
                if (sqrt((b.locx - self.player1.locx )**2 + (b.locy - self.player1.locy )**2 ) <= self.player1.speed):
                    map[b.locx][b.locy].m.setTexture(self.mTex,1)
                    map[b.locx][b.locy].canReach = True
                else:
                    map[b.locx][b.locy].canReach = False
        
         base.graphicsEngine.renderFrame()
    def printLoc(self):
        obj = self.hovSquare #.findNetTag("Tile")
        rockName = obj.getNetTag('Tile') 
                
        realobj = map[int(rockName[0])][int(rockName[2])]
                
        print "HELLO"
        print realobj.locx, ",", realobj.locy
        print map[realobj.locx][realobj.locy].m.getTexture()
        #import pdb; pdb.set_trace()
    
    def mouseTask(self, task):
        self.selSquare = None
        if base.mouseWatcherNode.hasMouse():
          #get the mouse position
          mpos = base.mouseWatcherNode.getMouse()
          
          #Set the position of the ray based on the mouse position
          self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
          
          #If we are dragging something, set the position of the object
          #to be at the appropriate point over the plane of the board
           #Gets the point described by pickerRay.getOrigin(), which is relative to
        #camera, relative instead to render
        nearPoint = render.getRelativePoint(camera, self.pickerRay.getOrigin())
            #Same thing with the direction of the ray
        nearVec = render.getRelativeVector(camera, self.pickerRay.getDirection())
        
      #Do the actual collision pass (Do it only on the squares for
      #efficiency purposes)
        self.picker.traverse(render)
        if self.pq.getNumEntries() > 0:
        #if we have hit something, sort the hits so that the closest
        #is first, and highlight that node
            self.pq.sortEntries()
            i = self.pq.getEntry(0).getIntoNodePath()
        #Set the highlight on the picked square
            self.hovSquare = i
        return Task.cont
        
            
app = App()
run()
            
    
"""class App(DirectObject):
    def __init__(self):
        self.tile = loader.loadModel("models/DungeonTile1")
        self.tile.setPos (0,70,0)
        self.tile.setHpr (0,45,0)
        self.tile.setScale(0.1)
        self.tile.reparentTo(render)
        
        self.tile2 = loader.loadModel("models/DungeonTile1")
        self.tile2.setPos (5.318,70,0)
        self.tile2.setHpr (0,45,0)
        self.tile2.setScale(0.1)
        self.tile2.reparentTo(render)
        
        self.title = OnscreenText(
            text="My Program",
            style=1, 
            fg=(1,1,1,1), 
            pos=(0,0), 
            scale = .07
        )
      

        camera.setPos (0,-60,0)
        camera.setHpr (0,-90,0)
        self.accept("escape", sys.exit, [0])
        self.accept("e", self.printText)
        base.setBackgroundColor(0, 0, 0)    #Set the background to black
    
    def printText(self):
        print camera.getPos()
    
app = App()
run()"""